package cc.rengu.igas.momp.core.service.trans;

import cc.rengu.igas.momp.common.constant.CommonConstant;
import cc.rengu.igas.momp.common.entity.McMchntFeeDiscountTransData;
import cc.rengu.igas.momp.common.entity.McMchntFeeDiscountTxnData;
import cc.rengu.utility.log.RgLogger;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 商户手续费优惠限额检查类
 *
 * @author liujinan
 * @version 1.0.0
 * @date 2021/7/16 17:45
 */

public class MchntFeeCheckLimitService {

    /**
     * 判断手续费优惠规则维度是否超限——优惠的手续费金额是否超限
     *
     * @param txnData        输入交易实体类
     * @param remainingQuota 本笔交易可优惠的手续费金额
     * @return mcMchntFeeDiscountTransData 输出交易实体类
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2021/7/8 14:55
     */
    public Object checkMfdRuleTotalAmtAndBudgetLimit(Object txnData, BigDecimal remainingQuota, RgLogger rglog) {
        String mchntTotalAmtAcc;
        String mchntDayTotalAmtAcc;
        String inputDiscountLimit;
        String mcNo;
        String mchntNo;
        String inputBudget;
        String inputMcTotalAmtAcc;
        String mchntFeeDiscount;

        if (txnData instanceof McMchntFeeDiscountTransData) {
            mchntTotalAmtAcc = ((McMchntFeeDiscountTransData) txnData).getMchntTotalAmtAcc();
            mchntDayTotalAmtAcc = ((McMchntFeeDiscountTransData) txnData).getMchntDayTotalAmtAcc();
            inputDiscountLimit = ((McMchntFeeDiscountTransData) txnData).getDiscountLimit();
            mcNo = ((McMchntFeeDiscountTransData) txnData).getMcNo();
            mchntNo = ((McMchntFeeDiscountTransData) txnData).getMchntNo();
            inputBudget = ((McMchntFeeDiscountTransData) txnData).getBudget();
            inputMcTotalAmtAcc = ((McMchntFeeDiscountTransData) txnData).getMcTotalAmtAcc();
            mchntFeeDiscount = ((McMchntFeeDiscountTransData) txnData).getMchntFeeDiscount();
        } else {
            mchntTotalAmtAcc = ((McMchntFeeDiscountTxnData) txnData).getMchntTotalAmtAcc();
            mchntDayTotalAmtAcc = ((McMchntFeeDiscountTxnData) txnData).getMchntDayTotalAmtAcc();
            inputDiscountLimit = ((McMchntFeeDiscountTxnData) txnData).getDiscountLimit();
            mcNo = ((McMchntFeeDiscountTxnData) txnData).getMcNo();
            mchntNo = ((McMchntFeeDiscountTxnData) txnData).getMchntNo();
            inputBudget = ((McMchntFeeDiscountTxnData) txnData).getBudget();
            inputMcTotalAmtAcc = ((McMchntFeeDiscountTxnData) txnData).getMcTotalAmtAcc();
            mchntFeeDiscount = ((McMchntFeeDiscountTxnData) txnData).getMchntFeeDiscount();
        }

        //手续费减免活动商户统计-累计优惠手续费金额
        BigDecimal totalAmtAcc = new BigDecimal(mchntTotalAmtAcc).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
        //手续费减免活动商户单日统计数据 具体规则-累计优惠手续费金额
        BigDecimal totalAmtAccDay = new BigDecimal(mchntDayTotalAmtAcc).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);

        //判断规则优惠上限(优惠手续费金额)是否超限
        BigDecimal discountLimit = new BigDecimal(inputDiscountLimit).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
        //本笔优惠手续费金额 + 周期统计累计优惠优惠手续费金额 + 单日统计累计优惠手续费金额
        BigDecimal totalDiscount = remainingQuota.add(totalAmtAcc).add(totalAmtAccDay).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);
        //周期统计累计优惠优惠手续费金额 + 单日统计累计优惠手续费金额
        BigDecimal historyTotalDiscount = totalAmtAcc.add(totalAmtAccDay).setScale(CommonConstant.DECIMAL_SCALE_TWO, RoundingMode.HALF_UP);

        rglog.info("规则优惠上限<{}>,不加本笔已累计优惠手续费金额<{}> 本笔手续费金额<{}> ", discountLimit, historyTotalDiscount, remainingQuota);

        if (CommonConstant.ZERO <= discountLimit.compareTo(totalDiscount)) {
            rglog.info("商户<{}>匹配到营销活动<{}>已累计优惠手续费金额<{}>加上本笔优惠手续费金额<{}>未超出规则限制<{}>,给予优惠！！！",
                    mchntNo, mcNo, historyTotalDiscount, totalDiscount, discountLimit);
        } else {
            rglog.info("加上本笔手续费优惠金额超出规则优惠手续费上限，继续判断不加本笔手续费优惠金额是否超限");
            if (CommonConstant.ZERO >= discountLimit.compareTo(historyTotalDiscount)) {
                rglog.info("商户<{}>匹配到营销活动<{}> 已累计优惠手续费金额<{}> 已超出规则手续费优惠上限<{}>,不予优惠！！！",
                        mchntNo, mcNo, historyTotalDiscount, discountLimit);
                return null;
            } else {
                rglog.info("商户<{}>匹配到营销活动<{}> 已累计优惠手续费金额<{}> 加上本笔优惠金额<{}> 加本笔已超过规则手续费优惠上限<{}>,仅可优惠<{}>！！！",
                        mchntNo, mcNo, historyTotalDiscount, totalDiscount, discountLimit, discountLimit.subtract(historyTotalDiscount));
                if (txnData instanceof McMchntFeeDiscountTransData) {
                    ((McMchntFeeDiscountTransData) txnData).setMchntFeeDiscount(discountLimit.subtract(historyTotalDiscount).toString());
                } else {
                    ((McMchntFeeDiscountTxnData) txnData).setMchntFeeDiscount(discountLimit.subtract(historyTotalDiscount).toString());
                }
            }
        }

        //判断总预算是否超限
        BigDecimal budget = new BigDecimal(inputBudget);
        if (budget.compareTo(BigDecimal.ZERO) > CommonConstant.ZERO) {
            //总预算累计消耗金额  包含统计表+单日+本流水除本明细外的所有金额
            BigDecimal mcTotalAmtAcc = new BigDecimal(inputMcTotalAmtAcc);
            //加本笔明细的汇总
            BigDecimal mcTotalAmtAccAddThisDet = mcTotalAmtAcc.add(new BigDecimal(mchntFeeDiscount));

            if (CommonConstant.ZERO <= budget.compareTo(mcTotalAmtAccAddThisDet)) {
                rglog.info("商户<{}>匹配到营销活动<{}>已累计优惠手续费金额<{}>加上本笔优惠手续费金额<{}>未超出总预算<{}>,给予优惠！！！", mchntNo, mcNo, mcTotalAmtAcc, mcTotalAmtAccAddThisDet, inputBudget);
            } else {
                rglog.info("加上本笔手续费优惠金额交易超出预算资金，继续判断不加本笔手续费优惠金额是否超出预算资金");
                if (CommonConstant.ZERO >= budget.compareTo(mcTotalAmtAcc)) {
                    rglog.info("商户<{}>匹配到营销活动<{}>已累计优惠手续费金额<{}>加上本笔优惠手续费金额<{}>超出总预算<{}>,不予优惠！！！", mchntNo, mcNo, mcTotalAmtAcc, mcTotalAmtAccAddThisDet, inputBudget);
                    return null;
                } else {
                    rglog.info("商户<{}>匹配到营销活动<{}>已累计优惠手续费金额<{}>加上本笔优惠手续费金额<{}>未超过总预算<{}>,仅可优惠<{}>！！！", mchntNo, mcNo, mcTotalAmtAcc, mcTotalAmtAccAddThisDet, inputBudget, budget.subtract(mcTotalAmtAcc));
                    if (txnData instanceof McMchntFeeDiscountTransData) {
                        ((McMchntFeeDiscountTransData) txnData).setMchntFeeDiscount(budget.subtract(mcTotalAmtAcc).toString());
                    } else {
                        ((McMchntFeeDiscountTxnData) txnData).setMchntFeeDiscount(budget.subtract(mcTotalAmtAcc).toString());
                    }
                }
            }
        } else {
            rglog.info("默认预算资金无上限,不判断是否超出预算资金");
        }

        return txnData;
    }

    /**
     * 判断手续费优惠周期维度是否超限
     *
     * @param txnData 输入交易实体类
     * @return mcMchntFeeDiscountTransData 输出交易实体类
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2021/7/9 14:55
     */
    public Object checkMfdPeriodTotalAmtAndBudgetLimit(Object txnData, String instId, String periodLimit, RgLogger rglog) {
        String txnDateInstId;
        String periodTotalAmtAcc;
        String mcNo;
        String mchntNo;
        String mchntFeeDiscount;

        if (txnData instanceof McMchntFeeDiscountTransData) {
            txnDateInstId = ((McMchntFeeDiscountTransData) txnData).getInstId();
            periodTotalAmtAcc = ((McMchntFeeDiscountTransData) txnData).getPeriodTotalAmtAcc();
            mcNo = ((McMchntFeeDiscountTransData) txnData).getMcNo();
            mchntNo = ((McMchntFeeDiscountTransData) txnData).getMchntNo();
            mchntFeeDiscount = ((McMchntFeeDiscountTransData) txnData).getMchntFeeDiscount();
        } else {
            txnDateInstId = ((McMchntFeeDiscountTxnData) txnData).getInstId();
            periodTotalAmtAcc = ((McMchntFeeDiscountTxnData) txnData).getPeriodTotalAmtAcc();
            mcNo = ((McMchntFeeDiscountTxnData) txnData).getMcNo();
            mchntNo = ((McMchntFeeDiscountTxnData) txnData).getMchntNo();
            mchntFeeDiscount = ((McMchntFeeDiscountTxnData) txnData).getMchntFeeDiscount();
        }

        BigDecimal periodTotalAmtLimit = BigDecimal.ZERO;
        //手续费优惠周期维度上限
        if (instId.equals(txnDateInstId)) {
            //银行行手续费营销活动周期数据为固定值
            periodTotalAmtLimit = new BigDecimal(periodLimit);
            rglog.info("商户<{}> 活动<{}> 活动周期为度限额为<{}>！", mchntNo, mcNo, periodTotalAmtLimit);
        } else {
        }
        //周期维度累计消耗金额 包含周期+单日+本流水除本明细外的所有金额
        BigDecimal mcPeriodTotalAmtAcc = new BigDecimal(periodTotalAmtAcc);
        //加本笔明细的汇总
        BigDecimal mcPeriodTotalAmtAccAddThisDet = mcPeriodTotalAmtAcc.add(new BigDecimal(mchntFeeDiscount));

        if (CommonConstant.ZERO <= periodTotalAmtLimit.compareTo(mcPeriodTotalAmtAccAddThisDet)) {
            rglog.info("商户<{}>匹配到营销活动<{}>已累计优惠金额<{}>加上本笔优惠金额<{}>未超出周期维度<{}>,给予优惠！！！", mchntNo, mcNo, mcPeriodTotalAmtAcc, mcPeriodTotalAmtAccAddThisDet, periodTotalAmtLimit);
        } else {
            rglog.info("加上本笔手续费优惠金额交易超出周期维度资金，继续判断不加本笔手续费优惠金额是否超出周期维度资金");
            if (CommonConstant.ZERO >= periodTotalAmtLimit.compareTo(mcPeriodTotalAmtAcc)) {
                rglog.info("商户<{}>匹配到营销活动<{}>已累计优惠金额<{}>加上本笔优惠金额<{}>超出周期维度<{}>,不予优惠！！！", mchntNo, mcNo, mcPeriodTotalAmtAcc, mcPeriodTotalAmtAccAddThisDet, periodTotalAmtLimit);
                return null;
            } else {
                rglog.info("商户<{}>匹配到营销活动<{}>已累计优惠金额<{}>加上本笔优惠金额<{}>未超出周期维度<{}>,仅可优惠<{}>！！！", mchntNo, mcNo, mcPeriodTotalAmtAcc, mcPeriodTotalAmtAccAddThisDet, periodTotalAmtLimit, periodTotalAmtLimit.subtract(mcPeriodTotalAmtAcc));
                if (txnData instanceof McMchntFeeDiscountTransData) {
                    ((McMchntFeeDiscountTransData) txnData).setMchntFeeDiscount(periodTotalAmtLimit.subtract(mcPeriodTotalAmtAcc).toString());
                } else {
                    ((McMchntFeeDiscountTxnData) txnData).setMchntFeeDiscount(periodTotalAmtLimit.subtract(mcPeriodTotalAmtAcc).toString());

                }
            }
        }
        return txnData;
    }

    /**
     * 判断手续费优惠周期维度是否超限
     *
     * @param txnData 输入交易实体类
     * @return boolean 判断是否已超限的结果
     * @throws Exception 异常信息
     * @author liujinan
     * @date 2021/7/21 14:55
     */
    public boolean checkMfdPeriodTotalAmtLimit(Object txnData, String instId, String periodLimit, RgLogger rglog) {
        String txnDateInstId;
        String periodTotalAmtAcc;
        String mcNo;
        String mchntNo;

        if (txnData instanceof McMchntFeeDiscountTransData) {
            txnDateInstId = ((McMchntFeeDiscountTransData) txnData).getInstId();
            periodTotalAmtAcc = ((McMchntFeeDiscountTransData) txnData).getPeriodTotalAmtAcc();
            mcNo = ((McMchntFeeDiscountTransData) txnData).getMcNo();
            mchntNo = ((McMchntFeeDiscountTransData) txnData).getMchntNo();
        } else {
            txnDateInstId = ((McMchntFeeDiscountTxnData) txnData).getInstId();
            periodTotalAmtAcc = ((McMchntFeeDiscountTxnData) txnData).getPeriodTotalAmtAcc();
            mcNo = ((McMchntFeeDiscountTxnData) txnData).getMcNo();
            mchntNo = ((McMchntFeeDiscountTxnData) txnData).getMchntNo();
        }

        BigDecimal periodTotalAmtLimit = BigDecimal.ZERO;
        //手续费优惠周期维度上限
        if (instId.equals(txnDateInstId)) {
            //银行行手续费营销活动周期数据为固定值
            periodTotalAmtLimit = new BigDecimal(periodLimit);
            rglog.info("商户<{}> 活动<{}> 活动周期为度限额为<{}>！", mchntNo, mcNo, periodTotalAmtLimit);
        } else {
        }

        //周期维度累计消耗金额
        BigDecimal mcPeriodTotalAmtAcc = new BigDecimal(periodTotalAmtAcc);

        if (mcPeriodTotalAmtAcc.compareTo(periodTotalAmtLimit) >= CommonConstant.ZERO) {
            rglog.info("机构<{}> 营销活动<{}> 周期限额已超限，退款不再回退额度", instId, mcNo);
            return false;
        }

        return true;
    }
}
